import React, { Component } from 'react'
import { message, Input, Button } from 'antd'
 
/**
 * React 组件生命周期
 * 
 * 1.组件的生命周期可分成三个状态
 * (1) Mounting(挂载)：已插入真实 DOM
 * (2) Updating(更新)：正在被重新渲染
 * (3) Unmounting(卸载)：已移出真实 DOM
 * 
 * 2.挂载
 * 当组件实例被创建时会调用如下方法。
 * (1) constructor(): 在 React 组件挂载之前，会调用它的构造函数。用于初始化组件的状态和绑定事件处理函数，在组件创建时只会被调用一次。其允许接收一个props参数，为组件的属性对象。
 * (2) getDerivedStateFromProps(): 在调用 render 方法之前调用，并且在初始挂载及后续更新时都会被调用。
 * (3) render(): render() 方法是 class 组件中唯一必须实现的方法。
 * (4) componentDidMount(): 在组件挂载后（插入 DOM 树中）立即调用。
 * 
 * 3.更新
 * 每当组件的 state 或 props 发生变化时，组件就会更新。
 * (1) getDerivedStateFromProps(): 在调用 render 方法之前调用，并且在初始挂载及后续更新时都会被调用。根据 shouldComponentUpdate() 的返回值，判断 React 组件的输出是否受当前 state 或 props 更改的影响。
 * (2) shouldComponentUpdate(): 当 props 或 state 发生变化时，shouldComponentUpdate() 会在渲染执行之前被调用。
 * (3) render(): render() 方法是 class 组件中唯一必须实现的方法。
 * (4) getSnapshotBeforeUpdate(): 在最近一次渲染输出（提交到 DOM 节点）之前调用。
 * (5) componentDidUpdate(): 在更新后会被立即调用。
 * 
 * 4.卸载
 * 当组件从 DOM 中移除时会调用如下方法。
 * (1) componentWillUnmount(): 在组件卸载及销毁之前直接调用。
 */
class Help extends React.Component {
  constructor(props) {
    super(props) // 继承父类(React.Component)的所有成员属性
 
    this.state = {
      title: '鸡你太美',
      date: new Date(),
      list: [
        { id: 1, name: 'aaa', status: true },
        { id: 2, name: 'bbb', status: true },
        { id: 3, name: 'ccc', status: false },
        { id: 4, name: 'ddd', status: false }
      ],
      isToggleOn: true,
    } // 定义一个名为 state 的成员属性
 
    this.handleSwitchClick = this.handleSwitchClick.bind(this) // 这边绑定是必要的，这样 `this` 才能在回调函数中使用
  }
 
  static getDerivedStateFromProps(props, state) {
    return {
      desc: `${state.title} ~`
    }
  }
 
  componentDidMount() {
    this.timerID = setInterval(
      () => this.handleChangeDatetime(),
      1000
    )
    console.log('Component DID MOUNT!')
  }
 
  componentDidUpdate(prevProps, prevState) {
    console.log('Component DID UPDATE!')
  }
 
  componentWillUnmount() {
    clearInterval(this.timerID)
    console.log('Component WILL UNMOUNT!')
  }
 
  // 定义一个名为 handleChangeDatetime 的成员方法
  handleChangeDatetime() {
    this.setState({ date: new Date() })
  }
 
  // 定义一个名为 handleButtonClick 的成员方法
  handleButtonClick(e) {
    console.log('handleButtonClick ->', e)
    message.open({ type: 'success', content: 'This is a success message' })
    message.open({ type: 'error', content: 'This is an error message' })
    message.open({ type: 'warning', content: 'This is an warning message' })
  }
 
  // 定义一个名为 handleSwitchClick 的成员方法
  handleSwitchClick() {
    console.log(this) // 获取本 Class 实例
    console.log(this.refs.buttonRef) // 获取 buttonRef 元素引用
    this.setState(prevState => (
      {
        isToggleOn: !prevState.isToggleOn
      }
    ))
  }
 
  render() {
    return (
      <>
        <div style={{
          display: 'flex',
          flexDirection: 'column',
          width: '100%',
          height: '100%',
          overflow: 'hidden',
          alignItems: 'center',
          justifyContent: 'center',
        }}>
          <p>Welcome to the page of Help!</p>
          <h1>{this.props.author}</h1>
          <Title name={this.state.desc} />
          <FormattedDate date={this.state.date} />
          <Button type="dashed" danger onClick={this.handleButtonClick}>要点击一下me吗</Button>
          <div>
            {
              this.state.list.map((item, index) => {
                return (
                  <li key={index}>
                  {
                    item.status
                    ? <span>已审核</span>
                    : <span>未审核</span>
                  }
                  </li>
                )
              })
            }
          </div>
          <div>
          <button ref="buttonRef"  onClick={this.handleSwitchClick}>{ this.state.isToggleOn ? 'ON' : 'OFF' }</button>
          </div>
        </div>
      </>
    )
  }
}
 
// 允许通过类组件的 defaultProps 属性为 props 设置默认值
Help.defaultProps = {
  author: '帅龍之龍'
}
 
// 定义一个名为 Title 的可接收 name 参数的类组件
class Title extends React.Component {
  render() {
    return (
      <h3 style={{ color: '#5e7ce0' }}>{this.props.name}</h3>
    )
  }
}
 
// 定义一个名为 FormattedDate 的可接收 props 参数的函数组件
const FormattedDate = (props) => {
  return <h2>现在是 {props.date.toLocaleTimeString()}</h2>
}
 
export default Help
